import java.awt.*;
import java.awt.event.*;
import javax.swing.*;



public class MultiplayerUI extends JFrame {
	
	private JComboBox numberOfPlayersComboBox;
	private JButton firstDoneButton;//holds the protocol for 1st try
	private JButton secondDoneButton;//holds the protocol for succeeding tries
	private ImagePanel panel;
	private JLabel numberOfPlayersLabel; 
	private MultiplayerComponentUI component[];
	private String tokens[];
	private Player p[];
	private int componentLimit;

	/**
	 * Create the frame.
	 */
	
	public MultiplayerUI() {
		//basic frame
		this.setBounds(100, 100, 580, 385); 
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.panel =  new ImagePanel(new ImageIcon("Graphics/MultiplayerUIBG.png").getImage());
		this.getContentPane().add(panel, BorderLayout.SOUTH);
		this.panel.setLayout(null);
		//declaring stuff
		String choice[] = {"-","2","3","4","5","6","7","8" };//choices for numberOfPlayersComboBox
		this.numberOfPlayersComboBox = new JComboBox(choice);
		this.component = new MultiplayerComponentUI[8];
		this.numberOfPlayersLabel = new JLabel("Number Of Players:");
		this.firstDoneButton = new JButton("Done");
		this.secondDoneButton = new JButton("Done");
		this.tokens = new String[16];
		//adding to the panel
		this.panel.add(this.numberOfPlayersComboBox);
		this.panel.add(this.firstDoneButton);
		this.panel.add(this.secondDoneButton);
		this.panel.add(this.numberOfPlayersLabel);
		//setting the added component
		this.numberOfPlayersLabel.setBounds(181, 157, 112, 14);
		this.numberOfPlayersComboBox.setBounds(301, 154, 37, 20);
		this.firstDoneButton.setBounds(216, 40, 100,50);
		this.secondDoneButton.setBounds(216, 40, 100,50);
		
		this.secondDoneButton.setVisible(false);//this will be visible if succeeding protocol is needed
		
		this.firstDoneButton.setVisible(false);//it will be visible after the user decides how many players are joining
		
		//initializing the components
		for(int counter = 0, yAxis = 100; counter <8; counter++){
			
			component[counter] = new MultiplayerComponentUI();
			panel.add(component[counter].getPlayerNameTextField());
			panel.add(component[counter].getTokenComboBox());
			panel.add(component[counter].getHighRollLabel());
			panel.add(component[counter].getDiceButton());
			
			panel.add(component[counter].getPlayerNameLabel());
			panel.add(component[counter].getTokenLabel());
			
			
			component[counter].getPlayerNameTextField().setBounds(20, yAxis, 120, 20);
			component[counter].getPlayerNameLabel().setBounds(20, yAxis, 120, 20);
			component[counter].getTokenComboBox().setBounds(148, yAxis, 150, 20);
			component[counter].getTokenLabel().setBounds(148, yAxis, 150, 20);
			component[counter].getHighRollLabel().setBounds(310, yAxis, 120, 14);
			component[counter].getDiceButton().setBounds(450, yAxis, 85, 20);
			
			component[counter].getPlayerNameTextField().setVisible(false);
			component[counter].getPlayerNameLabel().setVisible(false);
			component[counter].getTokenComboBox().setVisible(false);
			component[counter].getTokenLabel().setVisible(false);
			component[counter].getHighRollLabel().setVisible(false);
			component[counter].getDiceButton().setVisible(false);
			component[counter].setActive(false);
			
			yAxis=yAxis+30;
			
			
		}
		
		this.tokens[0] = ("Graphics/0.png");
		this.tokens[1] = ("Graphics/1.png");
		this.tokens[2] = ("Graphics/2.png");
		this.tokens[3] = ("Graphics/3.png");
		this.tokens[4] = ("Graphics/4.png");
		this.tokens[5] = ("Graphics/5.png");
		this.tokens[6] = ("Graphics/6.png");
		this.tokens[7] = ("Graphics/7.png");
		this.tokens[8] = ("Graphics/8.png");
		this.tokens[9] = ("Graphics/9.png");
		this.tokens[10] = ("Graphics/10.png");
		this.tokens[11] = ("Graphics/11.png");
		this.tokens[12] = ("Graphics/12.png");
		this.tokens[13] = ("Graphics/13.png");
		this.tokens[14] = ("Graphics/14.png");
		this.tokens[15] = ("Graphics/15.png");
		
		this.numberOfPlayersComboBox.addItemListener( //this is what happens when you choose a number

				new ItemListener(){
					
					@Override
					public void itemStateChanged(ItemEvent event){
						
						if(event.getStateChange() == ItemEvent.SELECTED){
							
							if(numberOfPlayersComboBox.getSelectedIndex() != 0){
								
								//next two lines is for locking the number of players
								numberOfPlayersComboBox.setVisible(false);
								numberOfPlayersLabel.setVisible(false);
								firstDoneButton.setVisible(true);//It makes sense now
														
								//this for is used to make a number of components depending one the choice of the user visible
								for(int counter = 0 ; counter < Integer.parseInt(numberOfPlayersComboBox.getSelectedItem().toString()); counter++){
									
									component[counter].getPlayerNameTextField().setVisible(true);
									component[counter].getTokenComboBox().setVisible(true);
									component[counter].getHighRollLabel().setVisible(true);
									component[counter].getDiceButton().setVisible(true);
									component[counter].setActive(true);
									componentLimit = counter+1;
									
								}
								
							}			
							
						}						
						
					}
				
				}
		
		);
		
		
		
		this.firstDoneButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
            	firstDoneButtonexitEvent(evt);
            }
        });
		
		this.secondDoneButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
            	secondDoneButtonexitEvent(evt);
            }
        });
		
		
	}
	//actionListeners
	
	
	private void firstDoneButtonexitEvent(ActionEvent evt) {
		
		if(!this.hasNoInputTextField()){
			
			if(!this.hasNamePassedCharacterLimit()){
				
				if(!this.hasDuplicateNames()){
					
					if(!this.hasDuplicateTokens()){
						
						if(!this.hasVisibleHighRollButtons()){
							
							this.getInputOnComponent();
							this.setPlayers();
							this.setHighRoll();
							this.sortWholePlayerArray();
							this.setQueueSpotOfWholePlayerArray();
							if(!this.hasSameQueueSpot()){
								
								BoardUI boardui = BoardUI.getInstance(this.p);
								this.dispose();
								
							}else{
								
								this.shiftComponentsOnMultiplayerUI();
								this.shiftDoneButton();				//shift from firstDoneButton to secondDoneButton
								this.showSameQueueSpotRollDiceButton();	//display Dice Button of sameQueueSpots 
								
							}
							
						}else{JOptionPane.showMessageDialog(null, "Nag-Error: May mga hindi pa nag papataasan");}
						
					}else{JOptionPane.showMessageDialog(null, "Nag-Error: May parehong token");}
					
				}else{JOptionPane.showMessageDialog(null, "Nag-Error: Merong parehong pangalan");}
				
			}else{JOptionPane.showMessageDialog(null, "Nag-Error: Hangang labing-lima lang ang dami ng letra para sa pangalan");}
		
		}else{JOptionPane.showMessageDialog(null, "Nag-Error: May Textfield na walang laman");}
			
	}
	
	private void secondDoneButtonexitEvent(ActionEvent evt) {
		
		if(!this.hasVisibleHighRollButtons()){
							
			this.setHighRoll();
			this.sortAndSetQueueSpotOfSucceedingRolls();
			if(!this.hasSameQueueSpot()){
								
					BoardUI boardui = BoardUI.getInstance(this.p);
					this.dispose();
								
				}else{
								
					
					this.showSameQueueSpotRollDiceButton();	//display Dice Button of sameQueueSpots 
								
			}
							
		}else{JOptionPane.showMessageDialog(null, "Nag-Error: May mga hindi pa nag papataasan");}
						
	}
	//end of actionListeners
	//Start of checkers
	
	private boolean hasNoInputTextField(){
		
		boolean returnValue = false;
		
		for(int counter = 0; counter<this.componentLimit;counter++){
			
				if(component[counter].getPlayerNameTextField().getText().isEmpty()){
					returnValue = true;
				}
		}
		
		return returnValue;
		
	}
	
	private boolean hasNamePassedCharacterLimit(){
		
		boolean returnValue = false; //true = no longer than 15
		String nameDecoy;
		
		for(int counter = 0; counter<this.componentLimit;counter++){
		
				nameDecoy = component[counter].getPlayerNameTextField().getText();
				if(nameDecoy.length() > 15){
					returnValue = true;
				}
			
		}
		
		return returnValue;
		
	}
	
	private boolean hasDuplicateNames(){
			
			boolean returnValue = false; //true = no longer than 15
			
			for(int counterOne = 0; counterOne<this.componentLimit; counterOne++){
				
				for(int counterTwo = 0; counterTwo<this.componentLimit; counterTwo++){
					
					if(counterOne != counterTwo){
						
						if(component[counterOne].getPlayerNameTextField().getText().equals(component[counterTwo].getPlayerNameTextField().getText()))
							returnValue = true;
					
					}
					
				}
				
			}
			
			return returnValue;
		
	}
	
	private boolean hasDuplicateTokens(){
		
		boolean returnValue = false; //true = no longer than 15
		
		for(int counterOne = 0; counterOne<this.componentLimit; counterOne++){
		
			for(int counterTwo = 0; counterTwo<this.componentLimit; counterTwo++){
				
				if(counterOne != counterTwo){
				
					if(component[counterOne].getTokenComboBox().getSelectedIndex() == component[counterTwo].getTokenComboBox().getSelectedIndex())
						returnValue = true;
				}
				
			}
			
		}
		
		return returnValue;
	
	}
	
	private boolean hasVisibleHighRollButtons(){
			
			boolean returnValue = false;
			
			for(int counter = 0; counter<this.componentLimit;counter++){
				
					if(component[counter].getDiceButton().isVisible()){
						returnValue = true;
					}
			}
			
			return returnValue;
		
	}
	
	private boolean hasSameQueueSpot(){
		
		boolean returnValue = false;
		
		for(int counter = 0; counter<this.componentLimit-1; counter++){// check if same queue spot
			
			if(p[counter].getQueueSpot() == p[counter+1].getQueueSpot())
				returnValue = true;
		
		}
		
		return returnValue;
		
	}
	
	
	
	//end of checkers
	
	//sorts
	
	private void sortWholePlayerArray(){
		
		Player holder;
		
		for(int arrayLength = p.length-1, limit = 0; arrayLength>limit; limit++){
			
			for(int lower = arrayLength, upper = lower-1 ; upper>=limit; lower--,upper--){
				
					if(p[upper].getHighRoll()<p[lower].getHighRoll()){
					
						holder = p[upper];
						p[upper] = p[lower];
						p[lower] = holder;
					
					}
					
			}
		
		}
		
	}
	
	
	//end of sorts
	
	private void sortAndSetQueueSpotOfSucceedingRolls(){
		
		Player holder = null;
		
		for(int counter = p.length-1; counter>0; counter--){
			
			if(p[counter].getQueueSpot() == p[counter-1].getQueueSpot()){
				
				
				
				for(int arrayLength = counter, limit = p[counter].getQueueSpot(); arrayLength>limit; limit++){
					
					for(int upper = arrayLength, lower = upper-1 ; upper>limit; lower--,upper--){
						
							if(p[upper].getHighRoll()>p[lower].getHighRoll()){
							
								holder = p[upper];
								p[upper] = p[lower];
								p[lower] = holder;
							
							}
							
							
					}
					
				}
				
				System.out.println("\n\n player: queue spot");
				for(Player x: p)
					System.out.println(x.getPlayerName() +" "+x.getQueueSpot());
				
				for(int traverser = p[counter].getQueueSpot(), queueCounter = traverser; traverser<=counter; traverser++){
					
					if(traverser != counter){
					
						p[traverser].setQueueSpot(queueCounter);
						
						if(p[traverser].getHighRoll() != p[traverser+1].getHighRoll()){
							
							queueCounter = traverser+1;
							
						}
					
					}else if(traverser == counter){
						
						if(p[traverser].getHighRoll() == p[traverser-1].getHighRoll()){
						
							p[traverser].setQueueSpot(p[traverser-1].getQueueSpot());
							
						
						}else{
						
							p[traverser].setQueueSpot(counter);
						
						
						}
					
					}
					
				}
			}
		
		}
		
		for(Player x: p)
			System.out.println(x.getPlayerName() +"   "+x.getHighRoll()+"   "+x.getQueueSpot());
		
	}
	
	//set queue spots
	
	private void setQueueSpotOfWholePlayerArray(){
		
		for(int counter = 0, queueCounter = 0; counter<p.length; counter++){
			
			if(counter != p.length-1){// checking if it is the last element
			
				
				p[counter].setQueueSpot(queueCounter);
				if(p[counter].getHighRoll() != p[counter+1].getHighRoll()){
					queueCounter = counter+1;
				}
			
			}else if(counter == p.length-1){
			
				if(p[counter].getHighRoll() == p[counter-1].getHighRoll()){
				
					p[counter].setQueueSpot(p[counter-1].getQueueSpot());
				
				}else{
				
					p[counter].setQueueSpot(p.length-1);
				
				}
			
			}
			
		}
		
	}
	
	//end of setting queueSpot
	private void setPlayers(){
		
		this.p = new Player[this.componentLimit];
		
		for(int counter = 0; counter<this.componentLimit;counter++){
				
				p[counter] = new Player(
										
										component[counter].getPlayerName(),
										this.tokens[component[counter].getTokenComboBox().getSelectedIndex()],
										counter
										);
				
		}
		
		
	}
	
	private void getInputOnComponent(){
		
		for(int counter = 0; counter<this.componentLimit;counter++){
			
			component[counter].getInput();
			
		}
		
	}
	
	private void setHighRoll(){
		
		for(int counterOne = 0; counterOne<this.componentLimit; counterOne++){
			
			for(int counterTwo = 0; counterTwo<this.componentLimit; counterTwo++){
				
					
					if(p[counterOne].getPlayerName().equals(component[counterTwo].getPlayerName())){
						
						p[counterOne].setHighRoll(component[counterTwo].getHighRoll());
						
					}
					
				
			}
			System.out.println(p[counterOne].getPlayerName() + " "+ p[counterOne].getHighRoll());
			
		}
		
		
	}
	
	//shift Components
	
	private void shiftComponentsOnMultiplayerUI(){
		
		for(int counter = 0; counter<this.componentLimit;counter++){
			
			component[counter].setVisibilityOfPhaseOneComponents(false);
			component[counter].setVisibilityOfPhaseTwoComponents(true);
			component[counter].setPhaseTwoComponents();
			
			
		}
		
	}
	
	private void shiftDoneButton(){
		
		this.firstDoneButton.setVisible(false);
		this.secondDoneButton.setVisible(true);
		
	}
	
	private void showSameQueueSpotRollDiceButton(){
		
		for(int counter = 0; counter<this.componentLimit; counter++){// check if same queue spot
			
				if(counter < this.componentLimit-1 && counter != 0){
					
					if(p[counter].getQueueSpot() == p[counter+1].getQueueSpot() || p[counter].getQueueSpot() == p[counter-1].getQueueSpot()){
							
						component[p[counter].getComponentPointer()].getDiceButton().setVisible(true);
						
					}
					
				}else{
					
					if(counter == 0){
						
						if(p[counter].getQueueSpot() == p[counter+1].getQueueSpot()){
							
							component[p[counter].getComponentPointer()].getDiceButton().setVisible(true);
							component[p[counter].getComponentPointer()].getDiceButton().setBackground(new Color(0, 0, 0, 0));
							component[p[counter].getComponentPointer()].getDiceButton().setForeground(new Color(0, 0, 0, 0));
							component[p[counter].getComponentPointer()].getDiceButton().setRolloverEnabled(false);
							component[p[counter].getComponentPointer()].getDiceButton()	.setBorderPainted(false);
							
						}
						
					}
					else if(counter == componentLimit-1){
						
						if(p[counter].getQueueSpot() == p[counter-1].getQueueSpot()){
							
							component[p[counter].getComponentPointer()].getDiceButton().setVisible(true);
							component[p[counter].getComponentPointer()].getDiceButton().setBackground(new Color(0, 0, 0, 0));
							component[p[counter].getComponentPointer()].getDiceButton().setForeground(new Color(0, 0, 0, 0));
							component[p[counter].getComponentPointer()].getDiceButton().setRolloverEnabled(false);
							component[p[counter].getComponentPointer()].getDiceButton().setBorderPainted(false);
						}
						
					}
					
					
				}
			
				
		}
		
			
		
	}
	
	//end of shift Components
	
	
	/**
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MultiplayerUI frame = new MultiplayerUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	**/
}
